package com.smartalarmclock.Model;

import java.util.HashSet;
import java.util.Set;

import android.content.Context;

import com.smartalarmclock.Model.IAlarmClock.ShutOffMethod;
import com.smartalarmclock.Model.Exceptions.DataEntityDoesNotExistException;

public final class AlarmClockFactory implements IReferencingDataEntityFactory {

	/**
	 * Public Constructor for new instances
	 * @param method the shut off method of the alarm clock
	 * @param isActive indicates if the alarm clock is active
	 * @param isRinging indicates if the alarm clock should ring,
	 * @param isVibrating indicates if the alarm clock should vibrate
	 * @param ringtoneId the id of the ringtone to use for the alarm clock
	 * @param snooze the Snooze instance for the alarm clock if "Snooze" is used
	 */
	public IAlarmClock CreateAlarmClock(
		ShutOffMethod method,
		boolean isActive,
		boolean isRinging,
		boolean isVibrating,
		int ringtoneId,
		ISnooze snooze) {
		return new AlarmClock(method, isActive, isRinging, isVibrating, ringtoneId, snooze);
	}
	
	/**
	 * Creates a new alarm clock, using all default values
	 */
	public IAlarmClock CreateAlarmClock() {
		return new AlarmClock();
	}
	
	/**
	 * Queries for an alarm clock instance with the given id
	 * @param context the context of the request (the originating Activity)
	 * @param id the id to query
	 * @return the matching AlarmClock instance with the given id.
	 * @throws DataEntityDoesNotExistException if the AlarmClock does not exist 
	 */
	public IAlarmClock GetAlarmClockById(Context context, int id) throws DataEntityDoesNotExistException {
		return AlarmClock.GetAlarmClockById(context, id);
	}
	
	/**
	 * Queries for an alarm clock instance with the given id
	 * @param context the context of the request (the originating Activity)
	 * @param id the id to query
	 * @return the matching AlarmClock instance with the given id, null if it doesn't exist 
	 */
	public IAlarmClock TryGetAlarmClockById(Context context, int id) {
		return AlarmClock.TryGetAlarmClockById(context, id);
	}
	
	/**
	 * Queries for an alarm clock instance with the given snooze settings
	 * @param context the context of the request (the originating Activity)
	 * @param snooze the snooze settings to check
	 * @return the matching AlarmClock instance with the given snooze settings.
	 * @throws DataEntityDoesNotExistException if the AlarmClock does not exist 
	 */
	public IAlarmClock GetAlarmClockBySnooze(Context context, ISnooze snooze) throws DataEntityDoesNotExistException {
		return AlarmClock.GetAlarmClockBySnooze(context, snooze);
	}
	
	/**
	 * Queries for an alarm clock instance with the given snooze settings
	 * @param context the context of the request (the originating Activity)
	 * @param snooze the snooze settings to check
	 * @return the matching AlarmClock instance with the given snooze settings, null if it doesn't exist 
	 */
	public IAlarmClock TryGetAlarmClockBySnooze(Context context, ISnooze snooze) {
		return AlarmClock.TryGetAlarmClockBySnooze(context, snooze);
	}

	/**
	 * @param context the context of the request
	 * @param referencedDataEntity the referencing entity
	 * @return a set of referencing entities for the given referenced entity
	 * @throws DataEntityDoesNotExistException if the referencing entities do not exist. If this is thrown
	 * something went wrong with the handling of the references.
	 */
	@Override
	public Set<IReferencingDataEntity> GetReferencingEntities(Context context, IReferencedDataEntity referencedDataEntity) throws DataEntityDoesNotExistException {
		Set<IReferencingDataEntity> alarmClocks = new HashSet<IReferencingDataEntity>();
		
		// Throws DataEntityDoesNotExistException. This is supposed to propagate because
		// no snooze entities should be in the DB if there is no alarm clock referencing it
		// (the delete method is to delete the snooze as well as the alarm clock)
		alarmClocks.add(GetAlarmClockBySnooze(context, (ISnooze)referencedDataEntity));
		return alarmClocks;
	}
}
